package com.gitee.wsl.collections.iterator


/**
 * 组合[Iterator]，将多个[Iterator]组合在一起，便于集中遍历。<br></br>
 * 来自Jodd
 *
 * @param <T> 元素类型
 * @author looly, jodd
</T> */
class ChainIterator<T> : Iterator<T> {
    protected val allIterators= ArrayList<Iterator<T>>()

    /**
     * 构造
     * 可以使用 [.addChain] 方法加入更多的集合。
     */
    constructor()

    /**
     * 构造
     * @param iterators 多个[Iterator]
     */
    constructor(vararg iterators: Iterator<T>) {
        for (iterator in iterators) {
            addChain(iterator)
        }
    }

    fun addChain(iterator: Iterator<T>): ChainIterator<T> {
        require(!allIterators.contains(iterator)) { "Duplicate iterator" }
        allIterators.add(iterator)
        return this
    }

    // ---------------------------------------------------------------- interface
    protected var currentIter: Int = -1

     override fun hasNext(): Boolean {
        if (currentIter == -1) {
            currentIter = 0
        }

        val size: Int = allIterators.size
        for (i in currentIter..<size) {
            val iterator = allIterators[i]
            if (iterator.hasNext()) {
                currentIter = i
                return true
            }
        }
        return false
    }

     override fun next(): T {
        if (!hasNext()) {
            throw NoSuchElementException()
        }

        return allIterators[currentIter].next()
    }

//    fun remove() {
//        check(-1 != currentIter) { "next() has not yet been called" }
//
//        allIterators.get(currentIter).remove()
//    }

      fun iterator(): Iterator<Iterator<T>> {
        return this.allIterators.iterator()
    }
}


class ChainMutableIterator<T> : MutableIterator<T> {
    protected val allIterators= ArrayList<MutableIterator<T>>()

    /**
     * 构造
     * 可以使用 [.addChain] 方法加入更多的集合。
     */
    constructor()

    /**
     * 构造
     * @param iterators 多个[Iterator]
     */
    constructor(vararg iterators: MutableIterator<T>) {
        for (iterator in iterators) {
            addChain(iterator)
        }
    }

    fun addChain(iterator: MutableIterator<T>): ChainMutableIterator<T> {
        require(!allIterators.contains(iterator)) { "Duplicate iterator" }
        allIterators.add(iterator)
        return this
    }

    // ---------------------------------------------------------------- interface
    protected var currentIter: Int = -1

     override fun hasNext(): Boolean {
        if (currentIter == -1) {
            currentIter = 0
        }

        val size: Int = allIterators.size
        for (i in currentIter..<size) {
            val iterator = allIterators[i]
            if (iterator.hasNext()) {
                currentIter = i
                return true
            }
        }
        return false
    }

     override fun next(): T {
        if (!hasNext()) {
            throw NoSuchElementException()
        }

        return allIterators[currentIter].next()
    }

    override fun remove() {
        check(-1 != currentIter) { "next() has not yet been called" }

        allIterators[currentIter].remove()
    }

      fun iterator(): MutableIterator<MutableIterator<T>> {
        return this.allIterators.iterator()
    }
}